package view;

import java.util.Observable;
import java.util.Observer;

import model.OnScreen;
import model.Snippet;
import model.location.Area;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;

public class SnippetView extends View implements Observer 
{
	private static final String TAG = SnippetView.class.getSimpleName();
	
	private Scanner _context;
	private Paint _paint;
	private Path _path;
	
	private Snippet _snippet;
	private int _deleteCounter = 0;
	
	private float ratio = 1f;
	private Area _area;
	private float x,y,width,height = 0;
	private boolean _status = false;
	
	private Handler handler = new Handler();
	private Runnable prepareForDeletion = new Runnable()
	{		
		@Override
		public void run() 
		{
			Log.d(TAG, "removing snippet");
			deleteView();
		}
	};
	
	public SnippetView(Context context, AttributeSet attrs, int defStyleAttr) 
	{
		super(context, attrs, defStyleAttr);
		init(context);
	}

	public SnippetView(Context context, AttributeSet attrs) 
	{
		super(context, attrs);
		init(context);
	}

	public SnippetView(Context context) 
	{
		super(context);
		init(context);
	}

	public void init(Context context) 
	{
		Log.d(TAG,String.format("New SnippetView"));
		
		_context = (Scanner) context;
		setLayoutParams(new LayoutParams(0,0));
		
		setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
		
		setLayerType(View.LAYER_TYPE_HARDWARE, _paint);		
		
		_paint = new Paint();
		_paint.setStyle(Paint.Style.FILL);
		
		_path = new Path();
		
		setWillNotCacheDrawing(true);
		setWillNotDraw(false);
		invalidate();
	}
	
	private void setSnippetData()
	{
		ratio = OnScreen.getInstance().getLeftTorightCodeScale();
		_area = _snippet.getScreenArea();
		x = _area.getCoordinate().getX();
		y = _area.getCoordinate().getY();
		width = _area.getDimension().getWidth();
		height =_area.getDimension().getHeight();
		_status = _snippet.isInformation();
		
		int color = _status ? Color.GREEN : Color.RED;
		_paint.setColor(color);
		
		Log.e("SQUARE", String.format("{%f, %f} -- %fx%f",x,y,width,height));
	}

	@Override
	public void update(Observable observable, Object data) 
	{		
		try {
			_snippet = (Snippet) observable;
		} catch (ClassCastException e) {
			Log.e(TAG, String.format("%s", e.toString()));
		}
		 
		if(_snippet == null)
			return;
		
		//Delete
		if(!_snippet.isInArea())
		{
			try 
			{
				//prepareForRemoval(_snippet);
				deleteView();
				return;
			} catch( Exception e) {
				Log.d(TAG, e.toString());
			}
		}
		else
		{
			_deleteCounter = 0;
			setVisibility(View.VISIBLE);
			handler.removeCallbacksAndMessages(null);
			setSnippetData();
			
			setWillNotCacheDrawing(true);
			setWillNotDraw(false);
			invalidate();
		}
	}
	
	@SuppressWarnings("unused")
	private void prepareForRemoval(Snippet snippet)
	{
		setVisibility(View.GONE);
		Log.d(TAG, String.format("Snippet %s no longer visible, scheduled to remove", snippet.getId()));
		
		handler.postDelayed(prepareForDeletion, 500);
	}
	
	private void deleteView() 
	{
		_deleteCounter++;
		if(_deleteCounter > 3)
		{
			_snippet.deleteObservers();
			_context.removeSnippetFromView(this);
		}
	}
	
	@Override
	protected void onDraw(Canvas canvas) 
	{
		super.onDraw(canvas);

		canvas.save();
		
		double margin;
		
		float[] yPoints;
		
		if(ratio >= 1.0f)
		{
			margin = ((height * ratio) - height) / 2;
			yPoints = new float[] {  y,
									y + (float) margin,
									y + height - (float) margin,
									y + height,
									y };
		}
		else
		{
			margin = ((height * (1/ratio)) - height) / 2;
			yPoints = new float[] { y + (float) margin,
									y,
									y + height,
									y + height - (float) margin,
									y + (float) margin };
		}

		drawSnippet(yPoints);
		canvas.drawPath(_path,_paint);
		
		canvas.restore();
	}	
	
	private void drawSnippet(float[] yPoints)
	{
		_path.reset();
		
		_path.moveTo(x, yPoints[0]);
		_path.lineTo(x + width, yPoints[1]);
		_path.lineTo(x + width, yPoints[2]);
		_path.lineTo(x, yPoints[3]);
		_path.lineTo(x, yPoints[4]);
	}
}